인증과 인가
: 자원을 적절한/유효한 사용자에게 전달/공개하기 위한 방법
- 인증 : 사용자의 신원을 확인하는 것
- 인가 : 신원이 확인된 사용자에게 리소스에 접근할 수 있는 권한을 부여하는 것
💡 인증이 선행된 후 인가가 이루어진다.
1. 인증하기(사용자)
- HTTP의 특징 : 무상태성(Stateless) ⇒서버는 클라이언트가 보낸 요청과 이 다음 요청에 대한 연관관계가 없다고 생각하고 요청에 대한 처리를 한다.
- Request Header 활용하기
브라우저
: 들어온 url에서 유저 정보를 파싱하고 Base64 인코더를 통해 인코딩을 한 후 요청 헤더의 Authorization에 넣어 전달한다서버
: 들어온 인증 정보를 기반으로 DB 체킹을 하고, DB에 실제로 값이 있는 경우 OK 사인을 해준다.
2. 인증 유지하기(Cookie, Client)
- 문제 : 사용자가 매번 로그인을 계속 해주어야 한다.(무상태성 때문에)
- 해결책 : 브라우저의 스토리지를 빌려보자!
- 쿠키
- 쿠키에 사용자의 정보를 넣어둔다.
- 사용자가 인증이 필요한 요청을 할 때 요청에 쿠키를 넣어서 보낸다.
- 사용자에게 편리함
3. 안전하게 인증하기(Session, Server)
- 문제 : 앞의 방법은 해커에게도 편리함(스토리지에 raw하게 저장되어 있기 떄문에) 💡 클라이언트는 서버보다 상대적으로 보안에 취약하다
- 해결책 : 서버를 활용해보자!
- 세션
- 사용자가 인증 정보가 포함된 요청을 보내면, 서버에 세션 정보가 저장된다.
- 이후 서버에서 클라이언트에게 보내는 응답 헤더에 세션 정보가 포함된다.
- 세션의 만료기간을 정할 수 있다.⇒보안적으로 이점
- 단점
- 서버가 여러개가 되면(feat. 로드밸런서), 서버 하나하나 자체에서 세션을 관리하게 되어 세션 정보를 제 때 가져오지 못하게 됨 ⇒세션 스토리지(=세션 DB)라는 것을 둬서 해결한다
- 클라이언트가 너무 많아지면 부하가 된다.
4. 효율적으로 인증하기(Token, Request/Response)
- 해결책 : 요청과 응답 안에 사용자의 상태를 담아보자.
- JWT(Json Web Token)
⇒사용자 정보(ex 이름), 토큰 만료 시기, 사용자의 권한(admin) 등을 포함하고 있다.
- 디코딩이 쉽기 때문에 비밀번호같은 정보는 담지 않는다.
- 세션과 달리 서버가 여러개라도 각 서버가 가진 시크릿 키로 해독을 해서 인증을 진행할 수 있다.
- 토큰으로 상태 관리를 하기 때문에 따로 세션을 둘 필요가 없다. 토큰도 탈취당할 수 있기 때문에 토큰 관리를 해주어야 한다.
- 매번 DB에 접근하지 않으므로 속도가 빠르다.
- 단점
- 액세스 토큰(Access Token)이 탈취당하면 쉽게 해킹당한다.
⇒만료기한을 정한다.
⇒사용자 입장에서 불편하니까 리프레쉬 토큰이라는 것을 적용한다.
- 리프레쉬 토큰(Refresh Token) : 서버가 액세스 토큰과 리프레쉬 토큰을 만든다. 리프레쉬 토큰은 서버에 저장. 이 둘을 응답으로 보내고, 클라이언트는 둘 다 저장한다. 이후 액세스 토큰이 만료되면, 클라이언트는 액세스 토큰과 리프레쉬 토큰을 요청으로 보내면 서버는 새로 갱신한 액세스 토큰을 보낸다.
- 액세스 토큰(Access Token)이 탈취당하면 쉽게 해킹당한다.
⇒만료기한을 정한다.
⇒사용자 입장에서 불편하니까 리프레쉬 토큰이라는 것을 적용한다.